package com.itheima.travel.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.travel.constant.RedisConstant;
import com.itheima.travel.mapper.FavoriteMapper;
import com.itheima.travel.mapper.RouteMapper;
import com.itheima.travel.mapperExt.FavoriteMapperExt;
import com.itheima.travel.mapperExt.RouteMapperExt;
import com.itheima.travel.pojo.Favorite;
import com.itheima.travel.pojo.FavoriteExample;
import com.itheima.travel.pojo.Route;
import com.itheima.travel.req.AffixVo;
import com.itheima.travel.req.FavoriteVo;
import com.itheima.travel.req.RouteVo;
import com.itheima.travel.service.AffixService;
import com.itheima.travel.service.FavoriteService;
import com.itheima.travel.service.RedisCacheService;
import com.itheima.travel.session.SubjectUser;
import com.itheima.travel.session.SubjectUserContext;
import com.itheima.travel.utils.BeanConv;
import com.itheima.travel.utils.EmptyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Description：收藏服务类
 */
@Service
public class FavoriteServiceImpl implements FavoriteService {

    @Autowired
    private FavoriteMapper favoriteMapper;

    @Autowired
    private FavoriteMapperExt favoriteMapperExt;

    @Autowired
    private RouteMapper routeMapper;

    @Autowired
    private RouteMapperExt routeMapperExt;

    @Autowired
    private SubjectUserContext subjectUserContext;

    @Autowired
    private AffixService affixService;

    @Autowired
    RedisCacheService redisCacheService;

    /**
     * PageInfo相当于我们自己封装的PageBean
     * 分页查询我的收藏
     * @param favoriteVo  封装当前用户的id
     * @param pageNum     当前页页码
     * @param pageSize    每页显示条数
     * 思路:
     *     在Mybatis中配置一个拦截器,拦截器指向的是pagehelper插件
     *     在Mybatis执行查询前后,调用pagehelper拼接sql和参数,完成分页查询
     * 在Mybatis中配置pagehelper插件 ★
     * @return   路线信息
     */
    @Override
    public PageInfo<RouteVo> findMyFavorite(FavoriteVo favoriteVo, int pageNum, int pageSize) {

        //添加redis缓存
        String key = RedisConstant.FAVORITESERVICE_FINDROUTEBYPAGE + pageNum + ":" + pageSize;
        return redisCacheService.singleCache(()->{
            // 首先将当前页页码以及每页显示条数交个 pagehelper
            //将pageNum，pageSize绑定到当前线程对象上
            PageHelper.startPage(pageNum,pageSize);
            //获取当前登录的用户
            SubjectUser subjectUser = subjectUserContext.getSubject();
            //分页查询
            //需要注意的是不要直接使用BeanConv对list进行copy,这样会到导致统计页面出错
            List<Route> list = favoriteMapperExt.findFavoriteByUserId(subjectUser.getId());
            // 封装查询结果 : 必须将pagehelper分页查询的结果存放到PageInfo中
            PageInfo<Route> pageInfo = new PageInfo<>(list);
            // 执行返回结果对象
            PageInfo<RouteVo>pageInfoVo = new PageInfo<>();
            // 拷贝pageInfo对象
            BeanConv.toBean(pageInfo,pageInfoVo);
            // 从分页的查询结果对象(pageInfo)中获取当前页的数据
            //List<Route> list1 = pageInfo.getList();
            List<RouteVo> routeVoList = BeanConv.toBeanList(pageInfo.getList(), RouteVo.class);
            pageInfoVo.setList(routeVoList);

            //处理图片问题
            for (RouteVo routeVo : routeVoList) {
                AffixVo affixVo = AffixVo.builder().businessId(routeVo.getId()).build();
                routeVo.setAffixVoList(affixService.findAffixByBusinessId(affixVo));
            }
            return pageInfoVo;
        },key);
        /*
        // 首先将当前页页码以及每页显示条数交个 pagehelper
        //将pageNum，pageSize绑定到当前线程对象上
        PageHelper.startPage(pageNum,pageSize);
        //获取当前登录的用户
        SubjectUser subjectUser = subjectUserContext.getSubject();
        //分页查询
        //需要注意的是不要直接使用BeanConv对list进行copy,这样会到导致统计页面出错
        List<Route> list = favoriteMapperExt.findFavoriteByUserId(subjectUser.getId());
        // 封装查询结果 : 必须将pagehelper分页查询的结果存放到PageInfo中
        PageInfo<Route> pageInfo = new PageInfo<>(list);
        // 执行返回结果对象
        PageInfo<RouteVo>pageInfoVo = new PageInfo<>();
        // 拷贝pageInfo对象
        BeanConv.toBean(pageInfo,pageInfoVo);
        // 从分页的查询结果对象(pageInfo)中获取当前页的数据
        //List<Route> list1 = pageInfo.getList();
        List<RouteVo> routeVoList = BeanConv.toBeanList(pageInfo.getList(), RouteVo.class);
        pageInfoVo.setList(routeVoList);

        //处理图片问题
        for (RouteVo routeVo : routeVoList) {
            AffixVo affixVo = AffixVo.builder().businessId(routeVo.getId()).build();
            routeVo.setAffixVoList(affixService.findAffixByBusinessId(affixVo));
        }
        return pageInfoVo;
        */
    }

    /**
     * 判断是否收藏
     * @param favoriteVo
     * @return
     */
    @Override
    public Boolean isFavorited(FavoriteVo favoriteVo) {
        //获取当前登录用户
        SubjectUser subjectUser = subjectUserContext.getSubject();
        //当未登录时
        if (EmptyUtil.isNullOrEmpty(subjectUser)){
            return false;
        }
        //设置查询规范（根据哪些条件进行查询）
        FavoriteExample favoriteExample = new FavoriteExample();
        favoriteExample.createCriteria().
                andRouteIdEqualTo(favoriteVo.getRouteId()).
                andUserIdEqualTo(subjectUser.getId());
        // 根据用户id和线路id查询中间表,判断是否收藏
        List<Favorite> favoriteList = favoriteMapper.selectByExample(favoriteExample);
        return favoriteList .size() > 0;
    }

    /**
     * 添加收藏
     *      1.向中间表添加一条记录
     *      2.修改线路的收藏次数
     *      3.查询当前线路的收藏次数
     * @param favoriteVo
     * @return
     */
    @Transactional
    @Override
    public Integer addFavorite(FavoriteVo favoriteVo) {
        //1.获取当前用户
        SubjectUser subjectUser = subjectUserContext.getSubject();
        favoriteVo.setUserId(subjectUser.getId());
        //2.向tab_favorite表插入一条数据
        favoriteMapper.insert(BeanConv.toBean(favoriteVo,Favorite.class));
        //3.更新tab_route表的count字段+1
        Long flag = routeMapperExt.updateRouteCountById(favoriteVo.getRouteId());
        if (flag == 0){
            throw  new RuntimeException("修改收藏次数出错");
        }
        //4.重新查询tab_route表的count字段
        Route route = routeMapper.selectByPrimaryKey(favoriteVo.getRouteId());
        return route.getAttentionCount();
    }
}
